package com.plat.api.api.action;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.plat.api.anonation.NoToken;
import com.plat.api.anonation.Token;
import com.plat.api.api.action.common.BuildOrderParam;
import com.plat.api.api.action.common.CommonMethod;
import com.plat.api.common.OrderType;
import com.plat.api.dao.api.*;
import com.plat.api.entity.api.*;
import com.plat.api.exception.PlatException;
import com.plat.api.mapper.PlatSubLiveMapper;
import com.plat.api.redis.RedisCache;
import com.plat.api.util.SnowflakeIdWorker;
import com.plat.api.util.YmalPropertiesUtil;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.beetl.sql.core.query.LambdaQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.math.BigDecimal;
import java.util.*;


/**
 * Created with IntelliJ IDEA.
 * User: shish
 * Date: 2020/7/11
 * Time: 13:28
 * Description: 直播相关接口
 */
@Slf4j
@Service
@Token
public class PlatLiveAction {
    @Autowired
    private WxPayService wxService;
    @Autowired
    private WxMaService wxMaService;

    @Autowired
    private UserDao userDao;

    @Autowired
    private TokenDao tokenDao;
    @Autowired
    private PlatWechatLiveRoomDao platWechatLiveRoomDao;
    @Autowired
    private PlatSubLiveMapper platSubLiveMapper;
    @Autowired
    private PlatOrderDao platOrderDao;
    @Autowired
    private PlatOrderDetailDao platOrderDetailDao;
    @Autowired
    private RedisCache redisCache;

    /**
     * 开房间直播
     */
    public JSONObject publish(JSONObject jsonObject) throws WxErrorException {
        String accessToken = wxMaService.getAccessToken();
        JSONObject param = jsonObject.getJSONObject("body");
        JSONObject head = jsonObject.getJSONObject("head");
        TokenEntity tokenEntity = tokenDao.getSQLManager().lambdaQuery(TokenEntity.class).andEq("token", head.getString("token")).single();
        UserEntity userEntity = CommonMethod.getUserEntity(tokenDao, userDao, jsonObject);
        String name = param.getString("name");
        Date startTime = param.getDate("startTime");
        Date endTime = param.getDate("endTime");
        String anchorName = param.getString("anchorName");
        String anchorWechat = param.getString("anchorWechat");
        String coverImgUrl = param.getString("coverImgUrl");
        String shareImgUrl = param.getString("shareImgUrl");
        Integer type = param.getInteger("type");
        Integer screenType = param.getInteger("screenType");
        Integer closeLike = param.getInteger("closeLike");
        Integer closeGoods = param.getInteger("closeGoods");
        Integer closeComment = param.getInteger("closeComment");
        String detail = param.getString("detail");
        Integer isFree = param.getInteger("isFree");
        Double price = param.getDouble("price");
        File file = FileUtil.file(YmalPropertiesUtil.getValue("sys.upload.url").toString() + "/" + RandomUtil.randomString(10) + "\\." + coverImgUrl.split("/")[coverImgUrl.split("/").length - 1].split("\\.")[1]);
        HttpUtil.downloadFile(coverImgUrl, file);
        WxMediaUploadResult coverImg = wxMaService.getMediaService().uploadMedia("image", new File(file.getPath()));
        log.info("上传文件名称：{}", file.getName());
        log.info("上传文件路径：{}", file.getPath());
        JSONObject jsonMap = new JSONObject();
        Long st = startTime.getTime() / 1000;
        Long et = endTime.getTime() / 1000;
        jsonMap.put("name", name);
        jsonMap.put("coverImg", coverImg.getMediaId());
        jsonMap.put("startTime", st);
        jsonMap.put("endTime", et);
        jsonMap.put("anchorName", anchorName);
        jsonMap.put("anchorWechat", anchorWechat);
        jsonMap.put("shareImg", coverImg.getMediaId());
        jsonMap.put("type", type);
        jsonMap.put("screenType", screenType);
        jsonMap.put("closeLike", closeLike);
        jsonMap.put("closeGoods", 1);
        jsonMap.put("closeComment", 0);
        jsonMap.put("closeShare", 1);
        jsonMap.put("closeReplay", 0);
        JSONObject json = new JSONObject();
        String js = jsonMap.toJSONString();
        try {
            String result = HttpUtil.post("https://api.weixin.qq.com/wxaapi/broadcast/room/create?access_token=" + accessToken, js);
            JSONObject res = JSONObject.parseObject(result);
            if (res.getLong("roomId") != null) {
                PlatWechatLiveRoomEntity entity = new PlatWechatLiveRoomEntity();
                entity.setName(name);
                entity.setCoverImg(coverImg.getMediaId());
                entity.setStartTime(startTime);
                entity.setEndTime(DateUtil.format(endTime, "yyyy-MM-dd hh:mm:ss"));
                entity.setAnchorName(anchorName);
                entity.setAnchorWechat(anchorWechat);
                entity.setShareImg(coverImg.getMediaId());
                entity.setType(type);
                entity.setScreenType(screenType);
                entity.setCloseLike(closeComment);
                entity.setCloseGoods(closeGoods);
                entity.setCloseComment(closeComment);
                entity.setPassword("");
                entity.setCoverImgUrl(coverImgUrl);
                entity.setShareImgUrl(shareImgUrl);
                entity.setDetail(detail);
                entity.setIsTop(0);
                entity.setDetail(detail);
                entity.setImageUrls("");
                entity.setIsCheck(0);
                entity.setRoomId(res.getLong("roomId"));
                entity.setIsOffonline(1);
                entity.setIsFree(isFree);
                entity.setPrice(price);
                entity.setPoster("");
                entity.setMediaUrl(String.valueOf(0));
                entity.setLiveStatus(102);//未开始
                entity.setSubNum(0);
                entity.setCreateUser(tokenEntity.getUserId());
                entity.setCreateName(userEntity.getName());
                entity.setField(userEntity.getField());
                entity.setReplayCreateStatus(0);
                platWechatLiveRoomDao.insert(entity);
                json.put("object", entity);
            } else {
                log.info("[发生错误信息：{}]", res);
                Map<String, Object> descMsg = getDesc(res);
                throw new PlatException(descMsg.get("code").toString(), descMsg.get("msg").toString(), descMsg.get("msg").toString());
            }
        } catch (PlatException e) {
            e.printStackTrace();
            log.info("[开通房间直播失败，请联系管理员]");
            throw new PlatException(e.getCode(), e.getDesc(), e.getDesc());
        }
        return json;
    }

    private Map<String, Object> getDesc(JSONObject res) {
        Map<String, Object> result = new HashMap<>();
        String msg;
        if (res.getString("errcode").equals("-1")) {
            msg = "微信系统错误";
            result.put("code", -1);
            result.put("msg", msg);
        } else if (res.getString("errcode").equals("1")) {
            msg = "未创建直播间";
            result.put("code", 1);
            result.put("msg", msg);
        } else if (res.getString("errcode").equals("300029")) {
            msg = "主播昵称违规";
            result.put("code", 300029);
            result.put("msg", msg);
        } else if (res.getString("errcode").equals("300028")) {
            msg = "房间名称违规";
            result.put("code", 300028);
            result.put("msg", msg);
        } else if (res.getString("errcode").equals("300001")) {
            msg = "禁止创建/更新商品 或 禁止编辑&更新房间";
            result.put("code", 300001);
            result.put("msg", msg);
        } else if (res.getString("errcode").equals("300002")) {
            msg = "名称长度不符合规则";
            result.put("code", 300002);
            result.put("msg", msg);
        } else if (res.getString("errcode").equals("300006")) {
            msg = "图片上传失败";
            result.put("code", 300006);
            result.put("msg", msg);
        } else if (res.getString("errcode").equals("300030")) {
            msg = "主播微信号不合法";
            result.put("code", 300030);
            result.put("msg", msg);
        } else if (res.getString("errcode").equals("300031")) {
            msg = "直播间封面图不合规";
            result.put("code", 300031);
            result.put("msg", msg);
        } else if (res.getString("errcode").equals("300035")) {
            msg = "主播微信号不存在";
            result.put("code", 300035);
            result.put("msg", msg);
        } else if (res.getString("errcode").equals("300036")) {
            msg = "主播微信号未实名认证";
            result.put("code", 300036);
        } else if (res.getString("errcode").equals("200002")) {
            msg = "开始时间结束时间无效，请检查";
            result.put("code", 200002);
        } else {
            msg = "其他问题，请联系管理";
            result.put("code", 300037);
        }
        result.put("msg", msg);
        return result;
    }

    @NoToken
    public JSONObject getLive(JSONObject jsonObject) {
        JSONObject param = jsonObject.getJSONObject("body");
        Integer id = param.getInteger("id");
        LambdaQuery<PlatWechatLiveRoomEntity> query = platWechatLiveRoomDao.getSQLManager().lambdaQuery(PlatWechatLiveRoomEntity.class);
        List<PlatWechatLiveRoomEntity> list = query.andEq("id", id).page(1, 1).getList();
        JSONObject json = new JSONObject();
        json.put("object", list.get(0));
        return json;
    }

    public JSONObject getLiveList(JSONObject jsonObject) throws WxErrorException {
        JSONObject head = jsonObject.getJSONObject("head");
        JSONObject body = jsonObject.getJSONObject("body");
        TokenEntity tokenEntity = tokenDao.getSQLManager().lambdaQuery(TokenEntity.class).andEq("token", head.getString("token")).single();
        UserEntity userEntity = userDao.unique(tokenEntity.getUserId());
        Map<String, List<PlatWechatLiveRoomEntity>> list1 = getPlatWechatLiveRoom(body, false, userEntity);
        JSONObject json = new JSONObject();
        json.put("list", JSON.toJSONString(list1.get("other"), SerializerFeature.DisableCircularReferenceDetect));
        json.put("liveList", JSON.toJSONString(list1.get("living"), SerializerFeature.DisableCircularReferenceDetect));
        json.put("object", userEntity);
        return json;
    }

    public Map<String, List<PlatWechatLiveRoomEntity>> getPlatWechatLiveRoom(JSONObject param, boolean isRand, UserEntity userEntity) throws WxErrorException {
        Integer page = param.getInteger("page");
        Integer pageSize = param.getInteger("pageSize");
        List<PlatWechatLiveRoomEntity> lv = platWechatLiveRoomDao.createLambdaQuery().andEq("live_status", 101).orderBy("id desc").page(page, pageSize).getList();
        List<PlatWechatLiveRoomEntity> oth = platWechatLiveRoomDao.createLambdaQuery().andNotEq("live_status", 101).orderBy("id desc").page(page, pageSize).getList();
        List<PlatWechatLiveRoomEntity> living = getLiveList(userEntity, soleList(lv));
        List<PlatWechatLiveRoomEntity> other = getLiveList(userEntity, soleList(oth));
        Map<String, List<PlatWechatLiveRoomEntity>> map = new HashMap<>();
        map.put("living", living);
        map.put("other", other);
        return map;
    }

    private List<PlatWechatLiveRoomEntity> solve(List<PlatWechatLiveRoomEntity> other) {
        List<PlatWechatLiveRoomEntity> list = new ArrayList<>();
        for (PlatWechatLiveRoomEntity roomEntity : other) {
           if (roomEntity.getLiveStatus().equals(103)||roomEntity.getLiveStatus().equals(102)||roomEntity.getLiveStatus().equals(105)||roomEntity.getLiveStatus().equals(106)){
               list.add(roomEntity);
           }
        }
        return list;
    }


    private List<PlatWechatLiveRoomEntity> soleList(List<PlatWechatLiveRoomEntity> list2) {
        List<PlatWechatLiveRoomEntity> list_1 = new ArrayList<>();
        for (PlatWechatLiveRoomEntity roomEntity : list2) {
            roomEntity.setStart_Time(DateUtil.format(roomEntity.getStartTime(), "MM-dd hh:mm"));
            list_1.add(roomEntity);
        }
        return list_1;
    }

    private List<PlatWechatLiveRoomEntity> getLiveList(UserEntity userEntity, List<PlatWechatLiveRoomEntity> list) {
        for (PlatWechatLiveRoomEntity roomEntity : list) {
            QueryWrapper<PlatLiveSubEntity> qw = new QueryWrapper<>();
            qw.eq("live_id", roomEntity.getId());
            qw.eq("user_id", userEntity.getId());
            Map<String, Object> map = new HashMap<>();
            map.put("live_id", roomEntity.getId());
            map.put("user_id", userEntity.getId());
            PlatLiveSubEntity platLiveSubEntity = platSubLiveMapper.selectOne(qw);
            if (platLiveSubEntity != null) {
                roomEntity.setIsSub(1);
            } else {
                roomEntity.setIsSub(0);
            }
            roomEntity.setSubNum(roomEntity.getSubNum());
            UserEntity user = new UserEntity();
            user.setName(roomEntity.getCreateName());
            user.setField(roomEntity.getField());
            roomEntity.setUser(user);
        }
        return list;
    }

    public JSONObject subLive(JSONObject jsonObject) throws WxPayException {
        JSONObject param = jsonObject.getJSONObject("body");
        JSONObject head = jsonObject.getJSONObject("head");
        TokenEntity tokenEntity = tokenDao.getSQLManager().lambdaQuery(TokenEntity.class).andEq("token", head.getString("token")).single();
        UserEntity userEntity = userDao.unique(tokenEntity.getUserId());
        QueryWrapper<PlatLiveSubEntity> qw = new QueryWrapper<>();
        qw.eq("live_id", param.getInteger("id"));
        qw.eq("user_id", tokenEntity.getUserId());
        PlatLiveSubEntity platLiveSubEntity = platSubLiveMapper.selectOne(qw);
        JSONObject result = new JSONObject();
        LambdaQuery<PlatWechatLiveRoomEntity> query = platWechatLiveRoomDao.getSQLManager().lambdaQuery(PlatWechatLiveRoomEntity.class).andEq("id", param.getInteger("id"));
        PlatWechatLiveRoomEntity roomEntity = query.single();
        if (platLiveSubEntity == null) {
            //发起订阅
            if (roomEntity.getPrice() != 0D) {
                String outTradeNo = SnowflakeIdWorker.getId();
                Object json = sub(roomEntity, userEntity, outTradeNo);
                PlatOrderEntity order = new PlatOrderEntity();
                BuildOrderParam buildOrderParam = new BuildOrderParam();
                buildOrderParam.setGoodsName(roomEntity.getName());
                buildOrderParam.setGoodsDetail(roomEntity.getDetail());
                buildOrderParam.setOrder(order);
                buildOrderParam.setPlatOrderDao(platOrderDao);
                buildOrderParam.setPlatOrderDetailDao(platOrderDetailDao);
                buildOrderParam.setUserEntity(userEntity);
                buildOrderParam.setOutTradeNo(outTradeNo);
                buildOrderParam.setPrice(roomEntity.getPrice());
                buildOrderParam.setGoodsId(roomEntity.getId());
                buildOrderParam.setOrderType(OrderType.LIVE);
                buildOrderParam.setExpressFee(new BigDecimal(0));
                CommonMethod.createOrder(buildOrderParam);
                result.put("pay", json);
                result.put("isSub", 0);
            } else {
                PlatLiveSubEntity subEntity = new PlatLiveSubEntity();
                subEntity.setLiveId(roomEntity.getId());
                subEntity.setUserId(userEntity.getId());
                subEntity.setStartTime(roomEntity.getStartTime());
                subEntity.setPayStatus(1);
                subEntity.setCreateTime(new Date());
                roomEntity.setSubNum(roomEntity.getSubNum() == null ? 0 + 1 : roomEntity.getSubNum() + 1);
                platWechatLiveRoomDao.updateById(roomEntity);
                platSubLiveMapper.insert(subEntity);
                result.put("pay", null);
                result.put("isSub", 1);
            }
        } else {
            result.put("isSub", 1);
        }
        result.put("sub", query.single());
        return result;
    }

    public Object sub(PlatWechatLiveRoomEntity roomEntity, UserEntity userEntity, String outTradeNo) throws WxPayException {
        WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();
        request.setOpenid(userEntity.getOpenId());
        String payBody = StringUtils.substring(roomEntity.getDetail(), 0, 25) + "...";
        request.setBody(payBody);
        request.setOutTradeNo(outTradeNo);
        Double p = roomEntity.getPrice() * 100;
        request.setTotalFee(p.intValue());
        request.setSpbillCreateIp("0.0.0.0");
        request.setNotifyUrl(YmalPropertiesUtil.getValue("wxpay.sub-notify-url").toString());
        request.setTradeType("JSAPI");
        WxPayMpOrderResult wxPayMpOrderResult = wxService.createOrder(request);
        return wxPayMpOrderResult;
    }

    public static void main(String[] args) {
        String url = "https://blog.csdn.net/qq_31255557/article/details/90346137/pan.png";
        System.out.println(url);
    }
}
